package top.haichi.webpaper.utils;

import com.alibaba.fastjson.JSONObject;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.util.StringUtils;


import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Date;
import java.util.Map;

@Slf4j
public class JwtUtils {

    private static final String privateKey = "zch6666666666";
    private static final Long expire = 43200000L;//有效时间

    /**
     * 生成JWT令牌
     *
     * @param claims
     * @return jwt第二部分负载 payload存储的内容
     */
    public static String generateJwt(Map<String, Object> claims) {
        String jwt = Jwts.builder()
                .addClaims(claims)
                .signWith(SignatureAlgorithm.HS256, privateKey)
                .setExpiration(new Date(System.currentTimeMillis() + expire))
                .compact();
        return jwt;
    }

    /**
     * 解析JWT令牌
     *
     * @param jwt
     * @return jwt第二部分负载 payload存储的内容
     */
    public static Claims parseJwt(String jwt) {
        Claims claims = Jwts.parser()
                .setSigningKey(privateKey)
                .parseClaimsJws(jwt)
                .getBody();
        return claims;
    }

    /**
     * 检查token与请求字段是否相同
     *
     * @param request
     * @param tokenParamName
     * @param requestParamName
     * @return
     */
    public static boolean verifyJwtWithParam(HttpServletRequest request, String tokenParamName, String requestParamName) {
        if(getJSONFromRequest(request)==null){
            return false;
        }

        String tokenParam = getTokenParam(request, tokenParamName);
        String requestParam = getJSONFromRequest(request)
                .getString(requestParamName);
        if (tokenParam == null || requestParam == null) {
            return false;
        }
        if (!tokenParam.equals(requestParam)) {
            log.warn("token与请求不一致,token:" + tokenParam + ",request:" + requestParam);
            return false;
        }
        return true;
    }

    /**
     * 根据param名称获取token中的param
     *
     * @param request
     * @param paramName
     * @return
     */
    public static String getTokenParam(HttpServletRequest request, String paramName) {
        if (!hasToken(request)) {
            return null;
        }
        String token = request.getHeader("token");
        try {
            log.info("获取到token:" + token);
            String param = JwtUtils.parseJwt(token).get(paramName).toString();
            return param;
        } catch (Exception e) {
            log.warn("token被修改或已过期,token:" + token);
            return null;
        }
    }

    /**
     * 检查请求中是否含有token
     *
     * @param request
     * @return
     */
    private static boolean hasToken(HttpServletRequest request) {
        String token = request.getHeader("token");
        if(token==null){
            return false;
        }
        else if (!StringUtils.hasLength(token)) {
            return false;
        }
        if(StringUtils.hasLength(token)){
            return true;
        }
        log.warn("token检查错误");
        return false;
    }

    /**
     * 从request请求体中获得JSON对象
     *
     * @param request
     * @return
     */
    private static JSONObject getJSONFromRequest(HttpServletRequest request) {
        String requestBody = InterceptorUtils.getRequestBody(request);
        JSONObject jsonObject = JSONObject.parseObject(requestBody);
        return jsonObject;
    }


}

